<template>
  <a-form
    :model="formState"
    :rules="formRules"
    ref="formRef"
    :label-col="{ span: 6 }"
    :wrapper-col="{ span: 16 }"
    @finish="handleSubmit"
  >
    <template v-for="item in formItems" :key="item.name">
      <!-- 输入框 -->
      <a-form-item v-if="item.type === 'input' || !item.type" :label="item.label" :name="item.name" :extra="item.extra">
        <a-input
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || `请输入${item.label}`"
          :disabled="item.disabled"
          :allow-clear="item.allowClear !== false"
        />
      </a-form-item>

      <!-- 数字输入框 -->
      <a-form-item v-else-if="item.type === 'number'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-input-number
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || `请输入${item.label}`"
          :disabled="item.disabled"
          :min="item.min"
          :max="item.max"
          :step="item.step || 1"
          style="width: 100%"
        />
      </a-form-item>

      <!-- 密码框 -->
      <a-form-item v-else-if="item.type === 'password'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-input-password
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || `请输入${item.label}`"
          :disabled="item.disabled"
          :allow-clear="item.allowClear !== false"
        />
      </a-form-item>

      <!-- 下拉选择 -->
      <a-form-item v-else-if="item.type === 'select'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-select
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || `请选择${item.label}`"
          :disabled="item.disabled"
          :allow-clear="item.allowClear !== false"
          :options="item.options"
          :mode="item.mode"
          :show-search="item.showSearch"
        />
      </a-form-item>

      <!-- 单选按钮 -->
      <a-form-item v-else-if="item.type === 'radio'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-radio-group v-model:value="formState[item.name]" :disabled="item.disabled" :options="item.options" />
      </a-form-item>

      <!-- 多选框 -->
      <a-form-item v-else-if="item.type === 'checkbox'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-checkbox-group v-model:value="formState[item.name]" :disabled="item.disabled" :options="item.options" />
      </a-form-item>

      <!-- 开关 -->
      <a-form-item v-else-if="item.type === 'switch'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-switch
          v-model:checked="formState[item.name]"
          :disabled="item.disabled"
          :checked-children="item.checkedChildren || '开启'"
          :un-checked-children="item.unCheckedChildren || '关闭'"
        />
      </a-form-item>

      <!-- 日期选择器 -->
      <a-form-item v-else-if="item.type === 'date'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-date-picker
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || `请选择${item.label}`"
          :disabled="item.disabled"
          :allow-clear="item.allowClear !== false"
          style="width: 100%"
          :show-time="item.showTime"
          :format="item.format || 'YYYY-MM-DD'"
        />
      </a-form-item>

      <!-- 时间选择器 -->
      <a-form-item v-else-if="item.type === 'time'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-time-picker
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || `请选择${item.label}`"
          :disabled="item.disabled"
          :allow-clear="item.allowClear !== false"
          style="width: 100%"
          :format="item.format || 'HH:mm:ss'"
        />
      </a-form-item>

      <!-- 日期范围选择器 -->
      <a-form-item v-else-if="item.type === 'range'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-range-picker
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || ['开始日期', '结束日期']"
          :disabled="item.disabled"
          :allow-clear="item.allowClear !== false"
          style="width: 100%"
          :show-time="item.showTime"
          :format="item.format || 'YYYY-MM-DD'"
        />
      </a-form-item>

      <!-- 上传组件 -->
      <a-form-item v-else-if="item.type === 'upload'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-upload
          v-model:file-list="formState[item.name]"
          :disabled="item.disabled"
          :multiple="item.multiple"
          :accept="item.accept"
          :list-type="item.listType || 'text'"
          :before-upload="item.beforeUpload || beforeUpload"
        >
          <a-button v-if="item.listType !== 'picture-card'">
            <upload-outlined></upload-outlined>
            点击上传
          </a-button>
          <div v-else>
            <plus-outlined></plus-outlined>
            <div style="margin-top: 8px">上传</div>
          </div>
        </a-upload>
      </a-form-item>

      <!-- 文本域 -->
      <a-form-item v-else-if="item.type === 'textarea'" :label="item.label" :name="item.name" :extra="item.extra">
        <a-textarea
          v-model:value="formState[item.name]"
          :placeholder="item.placeholder || `请输入${item.label}`"
          :disabled="item.disabled"
          :allow-clear="item.allowClear !== false"
          :rows="item.rows || 4"
          :show-count="item.showCount"
          :maxlength="item.maxlength"
        />
      </a-form-item>
    </template>

    <a-form-item :wrapper-col="{ offset: 6, span: 16 }">
      <a-space>
        <a-button type="primary" html-type="submit">提交</a-button>
        <a-button @click="handleReset">重置</a-button>
      </a-space>
    </a-form-item>
  </a-form>
</template>

<script setup>
import { ref, reactive, watch, onMounted } from "vue";
import { UploadOutlined, PlusOutlined } from "@ant-design/icons-vue";

const props = defineProps({
  // 表单配置项
  formItems: {
    type: Array,
    required: true,
    default: () => [],
    validator: (value) => {
      return value.every((item) => item.name && item.label);
    },
  },
  // 初始值
  initialValues: {
    type: Object,
    default: () => ({}),
  },
});

const emit = defineEmits(["submit", "reset"]);

const formRef = ref();
const formState = reactive({});
const formRules = reactive({});

// 初始化表单数据和校验规则
const initForm = () => {
  props.formItems.forEach((item) => {
    // 确保所有字段都被初始化
    if (!(item.name in formState)) {
      formState[item.name] = props.initialValues[item.name] ?? getDefaultValueByType(item.type);
    }

    // 初始化校验规则
    if (item.rules) {
      formRules[item.name] = item.rules;
    }
  });
};
// 提交表单
const handleSubmit = () => {
  formRef.value
    .validate()
    .then(() => {
      emit("submit", formState);
    })
    .catch((error) => {
      console.log("验证失败:", error);
    });
};

// 重置表单
const handleReset = () => {
  formRef.value.resetFields();
  emit("reset");
};

// 上传前处理
const beforeUpload = (file) => {
  const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
  if (!isJpgOrPng) {
    message.error("只能上传 JPG/PNG 文件!");
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error("图片大小不能超过 2MB!");
  }
  return isJpgOrPng && isLt2M;
};

// 暴露方法给父组件
defineExpose({
  validate: () => formRef.value.validate(),
  resetFields: () => formRef.value.resetFields(),
  getFormData: () => formState,
  setFieldsValue: (values) => {
    Object.keys(values).forEach((key) => {
      if (formState[key] !== undefined) {
        formState[key] = values[key];
      }
    });
  },
});
// 根据类型获取默认值
const getDefaultValueByType = (type) => {
  switch (type) {
    case "checkbox":
      return [];
    case "switch":
      return false;
    case "upload":
      return [];
    case "number":
      return null;
    case "select":
      return undefined;
    case "radio":
      return undefined;
    default:
      return undefined;
  }
};
// 监听初始值变化
watch(
  () => props.initialValues,
  (newVal) => {
    Object.keys(newVal).forEach((key) => {
      if (formState[key] !== undefined) {
        formState[key] = newVal[key];
      }
    });
  },
  { deep: true }
);

// 组件挂载时初始化
onMounted(() => {
  initForm();
});
</script>
